#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import logging
from datetime import datetime
from typing import List

from models import db
from utils.generate_id import GenerateID
from models.resource import Resource
from models.sso_user import SsoUser
from controller.resourceController import ResourceController
from utils.loggings import loggings
from utils.response_code import RET, error_map_EN

# 设置日志记录
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)


class ResourceService(ResourceController):
    upload_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'uploads', 'resource')
    upload_base = os.path.join('uploads', 'resource')
    @classmethod
    def add_or_update_resource(cls, **kwargs: dict) -> dict:
        """
        添加或更新资源，若资源已存在则更新，若不存在则添加。
        :param user_id: 用户ID
        :param file: 上传的文件对象
        :return: 资源ID
        """
        user_id = kwargs.get('user_id')
        file = kwargs.get('file')
        resource_id = kwargs.get('resource_id')

        try:
            # 获取文件扩展名并确定资源类型
            file_extension = os.path.splitext(file.filename)[1].lower()
            resource_type = cls._get_resource_type(file_extension)
            # 生成文件的存储路径
            file_location = cls.get_file_location(user_id, file_extension)
            file.save(file_location)

            if resource_id:
                # 更新已有资源
                resource = cls.get(user_id=user_id, resource_id=resource_id)
                if resource['code'] != RET.OK:
                    return resource
                resource = resource['data']

                res_update = cls.update({
                    'resource_id': resource_id,
                    'location': file_location,
                    'resource_type': resource_type
                })
                return res_update

            # 如果资源不存在，则生成新的资源ID
            resource_id = GenerateID.create_random_id()
            new_resource = Resource(
                resource_id=resource_id,
                user_id=user_id,
                location=file_location,
                resource_type=resource_type,
            )
            db.session.add(new_resource)
            db.session.commit()

            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': {'resource_id': resource_id}}

        except Exception as e:
            loggings.exception(1, f"Error adding or updating resource: {e}")
            return {'code': RET.DATAERR, 'message': error_map_EN[RET.DATAERR], 'data': {'error': str(e)}}

    @classmethod
    def _get_resource_type(cls, file_extension: str) -> int:
        """
        根据文件扩展名确定资源类型
        :param file_extension: 文件扩展名
        :return: 资源类型
        """
        image_types = ['.jpg', '.png', '.jpeg', '.gif']
        video_types = ['.mp4', '.avi', '.mov']

        if file_extension in image_types:
            return 1  # 图片类型
        elif file_extension in video_types:
            return 2  # 视频类型
        else:
            logger.error(f"Unsupported file type: {file_extension}")
            raise ValueError("Unsupported file type")

    @classmethod
    def get_file_location(cls, user_id: str, file_extension: str) -> str:
        """
        根据上传的文件生成存储路径
        :param user_id: 用户ID
        :param file_extension: 文件扩展名
        :return: 文件的存储路径
        """
        timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")
        new_file_name = f"{timestamp}{file_extension}"
        user_dir = os.path.join(cls.upload_base, user_id)
        file_location = os.path.join(user_dir, new_file_name)
        os.makedirs(os.path.join(cls.upload_dir, user_id), exist_ok=True)

        logger.info(f"Generated file location: {file_location}")
        return file_location

    @classmethod
    def delete_resource(cls, resource_id: str) -> bool:
        """
        删除资源，实际上将其标记为删除而不是物理删除
        :param resource_id: 资源ID
        :return: 是否删除成功
        """
        try:
            resource = db.session.query(Resource).filter_by(resource_id=resource_id).first()

            if not resource:
                logger.warning(f"Resource not found with ID: {resource_id}")
                return False

            resource.is_deleted = 1  # 标记为删除
            db.session.commit()
            logger.info(f"Resource with ID {resource_id} marked as deleted.")
            return True
        except Exception as e:
            db.session.rollback()
            logger.error(f"Error deleting resource: {e}")
            return False
        finally:
            db.session.close()

    @classmethod
    def get_all_resources(cls, **kwargs: dict) -> dict:
        """
        获取所有资源的列表，可以支持分页和筛选条件。
        :param user_id: 用户ID（可选）
        :param page: 当前页码
        :param page_size: 每页大小
        :param resource_type: 资源类型（可选）
        :param is_deleted: 是否已删除（可选）
        :return: 返回资源列表及分页信息
        """
        user_id = kwargs.get('user_id')
        page = kwargs.get('page', 1)
        page_size = kwargs.get('page_size', 10)
        resource_type = kwargs.get('resource_type')
        is_deleted = kwargs.get('is_deleted', 0)

        try:
            query = db.session.query(Resource).filter(Resource.is_deleted == is_deleted)

            if user_id:
                print(user_id)
                query = query.filter(Resource.user_id == user_id)

            if resource_type:
                query = query.filter(Resource.resource_type == resource_type)

            resources = query.offset((page - 1) * page_size).limit(page_size).all()

            total_count = query.count()

            resource_list = [cls._format_resource(resource) for resource in resources]

            return {
                'code': RET.OK,
                'message': error_map_EN[RET.OK],
                'data': {
                    'resources': resource_list,
                    'total_count': total_count,
                    'page': page,
                    'page_size': page_size
                }
            }

        except Exception as e:
            loggings.exception(1, f"Error fetching resources: {e}")
            return {'code': RET.DATAERR, 'message': error_map_EN[RET.DATAERR], 'data': {'error': str(e)}}

    @staticmethod
    def _format_resource(resource: Resource) -> dict:
        """
        格式化资源对象为字典格式
        :param resource: 资源对象
        :return: 格式化后的资源字典
        """
        return {
            'resource_id': resource.resource_id,
            'user_id': resource.user_id,
            'resource_type': resource.resource_type,
            'location': resource.location,
            'is_deleted': resource.is_deleted,
        }



    @classmethod
    def get_user_id(cls, **kwargs: dict) -> dict:
        account = kwargs.get('account')
        try:
            # 查询数据库中是否存在对应的用户
            user = db.session.query(SsoUser).filter(SsoUser.account == account).first()
            # print(user)
            if user:
                return {
                    "code": 200,
                    "message": "user_id 查询成功",
                    "data": {"user_id": user.user_id}
                }
            else:
                return {
                    "code": 404,
                    "message": f"未找到对应的用户: {account}",
                    "data": None
                }

        except Exception as e:
            # 捕获查询或其他异常
            return {
                "code": 500,
                "message": f"数据库查询错误: {str(e)}",
                "data": None
            }
